<template>
  <div class="admin-container">
    <!-- 页面标题区域 -->
    <div class="page-header">
      <div class="header-content">
        <h1 class="page-title">管理员日志记录</h1>
        <p class="page-description">查看所有管理员的操作记录和活动日志</p>
      </div>
      <div class="page-actions">
        <el-button type="primary" size="large" @click="$router.push('/admin')">
          <el-icon><ArrowLeft /></el-icon> 返回管理员
        </el-button>
        <el-button size="large" @click="fetchAdminLogs" :loading="loading">
          <el-icon><RefreshRight /></el-icon> 刷新
        </el-button>
      </div>
    </div>
    
    <!-- 日志表格区域 -->
    <div class="row-container">
      <el-card class="table-card" shadow="hover">
        <template #header>
          <div class="card-header">
            <div class="card-title">
              <i class="el-icon-data-analysis"></i> 
              管理员日志记录
            </div>
            <el-select
              v-model="selectedOperation"
              placeholder="筛选操作类型"
              clearable
              size="small"
              style="width: 180px; margin-left: 16px"
              @change="handleOperationFilter"
              :disabled="loading"
            >
              <el-option
                v-for="item in operationOptions"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              />
            </el-select>
          </div>
        </template>
        
        <el-table
          :data="paginatedLogs"
          style="width: 100%"
          v-loading="loading"
          :header-cell-style="{backgroundColor: '#f0f5ff', color: '#1e3799', fontWeight: '600', padding: '18px 10px'}"
          :cell-style="{padding: '16px 20px', textAlign: 'center'}"
          border
          stripe
          highlight-current-row
          :row-class-name="tableRowClassName"
          class="admin-log-table"
        >
          <el-table-column prop="timestamp" label="时间" width="220" sortable align="center" class-name="timestamp-column">
            <template #default="scope">
              <div class="time-column">
                <el-tooltip :content="scope.row.timestamp" placement="top">
                  <div class="time-display">
                    <span>{{ formatDateTimeInline(scope.row.timestamp) }}</span>
                  </div>
                </el-tooltip>
              </div>
            </template>
          </el-table-column>
          <el-table-column prop="admin_name" label="管理员" width="180" align="center" class-name="admin_name-column">
            <template #default="scope">
              <el-tag size="default" effect="plain" class="admin-tag">{{ scope.row.admin_name }}</el-tag>
            </template>
          </el-table-column>
          <el-table-column label="操作类型" width="280" align="center" class-name="operation-column">
            <template #default="scope">
              <div class="operation-type-container">
                <el-tag :type="getOperationTagType(scope.row.operation)" effect="dark" class="operation-tag">
                  {{ formatOperation(scope.row.operation) }}
                </el-tag>
              </div>
            </template>
          </el-table-column>
          <el-table-column prop="ip" label="IP地址" width="220" align="center" class-name="ip-column">
            <template #default="scope">
              <el-tooltip content="点击复制IP" placement="top">
                <span class="ip-address" @click="copyToClipboard(scope.row.ip)">{{ scope.row.ip }}</span>
              </el-tooltip>
            </template>
          </el-table-column>
          <el-table-column label="详细信息" min-width="120" align="left" class-name="details-column">
            <template #default="scope">
              <div class="log-summary">
                <span class="operation-summary">{{ getOperationSummary(scope.row) }}</span>
              </div>
            </template>
          </el-table-column>
        </el-table>
        
        <div class="pagination">
          <el-pagination
            v-if="serverTotalLogs > 0"
            @current-change="handleCurrentChange"
            @size-change="handleSizeChange"
            :current-page="currentPage"
            :page-size="pageSize"
            :page-sizes="[10, 20, 50, 100]"
            layout="total, sizes, prev, pager, next, jumper"
            :total="serverTotalLogs"
            :disabled="loading">
          </el-pagination>
        </div>
        
        <!-- 加载更多按钮 -->
        <el-button
          v-if="!loading && logs.length < serverTotalLogs"
          type="primary"
          size="large"
          style="margin: 24px auto 0; display: block;"
          @click="loadMoreLogs"
        >
          加载更多
        </el-button>
        
        <!-- 分页信息提示 -->
        <div class="pagination-info" v-if="serverTotalLogs > 0">
          <el-divider>
            <span class="divider-content">当前显示 {{ (currentPage-1) * pageSize + 1 }}-{{ Math.min(currentPage * pageSize, serverTotalLogs) }} 条，共 {{ serverTotalLogs || 0 }} 条日志</span>
          </el-divider>
        </div>
        
        <!-- 无数据提示 -->
        <div v-if="!loading && logs.length === 0" class="no-data-tip">
          <el-empty description="暂无日志数据"></el-empty>
        </div>
      </el-card>
    </div>
    
    <!-- 浮动操作区 -->
    <div class="floating-actions">
      <el-button type="primary" @click="fetchPageData" :loading="loading" class="refresh-btn">
        <el-icon><RefreshRight /></el-icon>
      </el-button>
    </div>
    
    <!-- 底部安全区域 -->
    <div class="bottom-safe-area"></div>
  </div>
</template>

<script>
import axios from 'axios'
import { 
  RefreshRight, 
  ArrowLeft
} from '@element-plus/icons-vue'
import { ElMessage } from 'element-plus'

export default {
  name: 'AdminLogsPage',
  components: {
    RefreshRight,
    ArrowLeft
  },
  data() {
    return {
      loading: false,
      adminInfo: {
        admin_id: '',
        admin_name: '',
        admin_level: 1
      },
      logs: [],
      currentPage: 1,
      pageSize: 20,
      selectedOperation: '',
      operationOptions: [
        { value: 'login', label: '系统登录' },
        { value: 'login_failed', label: '登录失败' },
        { value: 'add_admin', label: '添加管理员' },
        { value: 'delete_admin', label: '删除管理员' },
        { value: 'update_admin', label: '更新管理员' },
        { value: 'change_authority', label: '修改权限' },
        { value: 'ban_admin', label: '禁用管理员' },
        { value: 'unban_admin', label: '解禁管理员' }
        /* 如需更多类型可补充 */
      ],
      // 日志自动刷新定时器
      logRefreshTimer: null,
      // 日志自动刷新间隔（毫秒）
      logRefreshInterval: 300000, // 5分钟刷新一次
      // 服务器总日志数
      serverTotalLogs: 0
    }
  },
  computed: {
    paginatedLogs() {
      // 首先过滤掉不需要显示的日志类型
      let filteredLogs = this.logs.filter(log => log.operation !== 'user_submit_feedback');
      
      // 如果有筛选条件，再按筛选条件过滤
      if (this.selectedOperation && this.selectedOperation.trim() !== '') {
        filteredLogs = filteredLogs.filter(log => log.operation === this.selectedOperation);
      }
      
      return filteredLogs;
    }
  },
  created() {
    // 从localStorage获取管理员信息
    const adminInfoStr = localStorage.getItem('adminInfo')
    if (adminInfoStr) {
      try {
        const adminInfo = JSON.parse(adminInfoStr)
        this.adminInfo = {
          ...this.adminInfo,
          ...adminInfo
        }
        console.log('已加载管理员信息:', this.adminInfo)
      } catch (error) {
        console.error('解析管理员信息失败:', error)
        // 如果解析失败，尝试从sessionStorage获取
        this.tryGetAdminInfoFromSession()
      }
    } else {
      // 如果localStorage没有，尝试从sessionStorage获取
      this.tryGetAdminInfoFromSession()
    }
    
    // 尝试从cookie或其他地方获取adminID
    this.checkAndSetAdminId()
    
    // 确保adminID存在
    if (!this.adminInfo.admin_id) {
      console.warn('管理员ID未找到，将影响日志查询')
      ElMessage.warning('管理员信息未完整加载，可能影响查询功能')
    }
    
    // 加载管理员日志
    this.fetchPageData()
    
    // 启动日志自动刷新
    this.startLogRefresh()
  },
  beforeUnmount() {
    // 组件销毁前清除定时器
    this.stopLogRefresh()
  },
  methods: {
    // 检查并设置adminID
    checkAndSetAdminId() {
      // 如果已经有adminID，不需要再查找
      if (this.adminInfo.admin_id) {
        return
      }
      
      // 尝试从cookie获取
      const getCookie = (name) => {
        const value = `; ${document.cookie}`
        const parts = value.split(`; ${name}=`)
        if (parts.length === 2) return parts.pop().split(';').shift()
      }
      
      const cookieAdminId = getCookie('adminID')
      if (cookieAdminId) {
        this.adminInfo.admin_id = cookieAdminId
        console.log('从cookie获取adminID:', cookieAdminId)
        return
      }
      
      // 尝试从URL参数获取
      const urlParams = new URLSearchParams(window.location.search)
      const urlAdminId = urlParams.get('adminID')
      if (urlAdminId) {
        this.adminInfo.admin_id = urlAdminId
        console.log('从URL获取adminID:', urlAdminId)
        return
      }
      
      // 检查axios默认headers
      if (axios.defaults.headers.common['adminID']) {
        this.adminInfo.admin_id = axios.defaults.headers.common['adminID']
        console.log('从axios默认headers获取adminID:', this.adminInfo.admin_id)
      }
    },
    
    // 从sessionStorage尝试获取管理员信息
    tryGetAdminInfoFromSession() {
      const sessionAdminInfo = sessionStorage.getItem('adminInfo')
      if (sessionAdminInfo) {
        try {
          const adminInfo = JSON.parse(sessionAdminInfo)
          this.adminInfo = {
            ...this.adminInfo,
            ...adminInfo
          }
          console.log('从sessionStorage加载管理员信息:', this.adminInfo)
        } catch (error) {
          console.error('从sessionStorage解析管理员信息失败:', error)
        }
      }
    },
    
    // 获取管理员日志
    fetchAdminLogs() {
      // 重置分页状态
      this.currentPage = 1
      
      // 使用fetchPageData获取数据
      this.fetchPageData()
    },
    
    // 根据当前页码获取数据
    fetchPageData() {
      if (!this.adminInfo.admin_id) {
        console.error('缺少管理员ID，无法获取日志')
        ElMessage.error('用户信息不完整，请重新登录')
        setTimeout(() => {
          this.$router.push('/login')
        }, 2000)
        return
      }
      this.loading = true
      const params = {
        page: this.currentPage,
        page_size: this.pageSize
      };
      if (this.selectedOperation) {
        params.operation = this.selectedOperation;
      }
      const requestConfig = {
        headers: {
          'adminID': this.adminInfo.admin_id
        },
        params: params
      }
      if (axios.defaults.headers.common['adminID']) {
        requestConfig.headers['adminID'] = axios.defaults.headers.common['adminID']
      }
      const apiUrl = 'https://smartsound.top/api/v1/admin/log_activity';
      axios.get(apiUrl, requestConfig)
        .then(response => {
          if (response.data && response.data.code === 0) {
            const data = response.data.data
            let logs = []
            if (Array.isArray(data)) {
              logs = data
            } else if (data.logs) {
              logs = data.logs || []
            }
            // 过滤掉operation为'register'的日志
            logs = logs.filter(log => log.operation !== 'register');
            // 日志去重逻辑
            const dedupMap = new Map()
            logs.forEach(log => {
              let normalizedOperation = log.operation
              if (log.operation === 'register_admin') normalizedOperation = 'add_admin'
              const key = `${log.timestamp.substr(0, 16)}_${log.admin_name}_${normalizedOperation}_${log.ip}`
              if (!dedupMap.has(key)) {
                dedupMap.set(key, log)
              } else {
                const exist = dedupMap.get(key)
                const hasDetails = log.details && (
                  (normalizedOperation === 'add_admin' && log.details.new_admin_name) || 
                  (normalizedOperation === 'delete_admin' && (log.details.target_admin_name || 
                    (log.details.deleted_admin && log.details.deleted_admin.admin_name)))
                )
                const existHasDetails = exist.details && (
                  (normalizedOperation === 'add_admin' && exist.details.new_admin_name) || 
                  (normalizedOperation === 'delete_admin' && (exist.details.target_admin_name || 
                    (exist.details.deleted_admin && exist.details.deleted_admin.admin_name)))
                )
                if (hasDetails && !existHasDetails) {
                  dedupMap.set(key, log)
                }
              }
            })
            this.logs = Array.from(dedupMap.values())
            this.serverTotalLogs = data.pagination ? data.pagination.total_logs : this.logs.length
          } else {
            const errorMsg = response.data.message || response.data.msg || '未知错误'
            ElMessage.error('获取日志失败: ' + errorMsg)
            this.logs = []
            this.serverTotalLogs = 0
          }
        })
        .catch(error => {
          if (error.response && error.response.status === 403) {
            ElMessage.error('后端限制，只有1级管理员能查看管理员日志，请联系后端开放权限给0级管理员！');
          } else {
            ElMessage.error('获取日志失败，请稍后重试');
          }
          this.logs = []
          this.serverTotalLogs = 0
        })
        .finally(() => {
          this.loading = false
        })
    },
    
    // 启动日志自动刷新
    startLogRefresh() {
      if (this.logRefreshTimer) {
        clearInterval(this.logRefreshTimer)
      }
      
      this.logRefreshTimer = setInterval(() => {
        console.log('自动刷新管理员日志')
        this.fetchPageData()
      }, this.logRefreshInterval)
    },
    
    // 停止日志自动刷新
    stopLogRefresh() {
      if (this.logRefreshTimer) {
        clearInterval(this.logRefreshTimer)
        this.logRefreshTimer = null
      }
    },
    
    // 复制到剪贴板
    copyToClipboard(text) {
      navigator.clipboard.writeText(text)
        .then(() => {
          ElMessage({
            type: 'success',
            message: '已复制到剪贴板'
          })
        })
        .catch(err => {
          console.error('复制失败:', err)
          ElMessage.error('复制失败')
        })
    },
    
    // 格式化日期时间为单行
    formatDateTimeInline(dateString) {
      const datePart = dateString.split(' ')[0];
      const [, month, day] = datePart.split('-');
      const timePart = dateString.split(' ')[1].substring(0, 5);
      return `${month}-${day} ${timePart}`;
    },
    
    // 格式化操作类型
    formatOperation(operation) {
      const operationMap = {
        'login': '系统登录',
        'login_failed': '登录失败',
        'password_change': '修改密码',
        'change_password': '修改密码',
        'change_name': '修改个人信息',
        'change_admin_name': '修改个人信息',
        'query': '查看用户列表',
        'update': '更新信息',
        'delete': '删除数据',
        'create': '创建记录',
        'delete_admin': '删除管理员',
        'query_admin_logs': '查看管理日志',
        'add_admin': '添加管理员',
        'register_admin': '创建管理员',
        'update_admin': '更新管理员',
        'update_status': '更新状态',
        'export_data': '导出数据',
        'upload_file': '上传文件',
        'download_file': '下载文件',
        'change_permission': '修改权限',
        'view_feedback': '查看了用户反馈',
        'reply_feedback': '回复了用户反馈',
        'list_feedback': '查看了反馈中心',
        'query_user_detail': '查看用户详情',
        'query_self_logs': '查看个人日志',
        'get_announcements': '查看了系统公告',
        'get_announcement_detail': '查看了公告详情',
        'update_announcement': '更新了系统公告',
        'create_announcement': '发布了新公告',
        'delete_announcement': '删除了系统公告',
        'query_admin_list': '查看了管理员列表',
        'query_music_overview': '查看了音乐数据概览',
        'query_device_activity': '查看了设备活跃曲线',
        'query_listening_distribution': '查看了听歌分布统计',
        'query_user_activity': '查看了用户活跃数据',
        'delete_device': '删除了用户设备',
        'get_feedback_replies': '回复了用户反馈',
        'change_authority': '修改了管理员权限',
        'get_device_status_stats': '查看了设备状态分布',
        'ban_admin': '禁用管理员',
        'unban_admin': '解禁管理员',
        'account_banned': '账号被禁用',
        'update_feedback_status': '更新反馈状态',
        'delete_user': '删除用户',
        'add_device': '添加设备',
        'toggle_admin_active': '修改管理员账户状态失败',
      }
      
      return operationMap[operation] || operation
    },
    
    // 获取操作类型对应的标签类型
    getOperationTagType(operation) {
      const typeMap = {
        'login': 'success',
        'login_failed': 'danger',
        'password_change': 'warning',
        'change_password': 'warning',
        'change_name': 'warning',
        'change_admin_name': 'warning',
        'query': 'info',
        'update': 'warning',
        'delete': 'danger',
        'create': 'success',
        'delete_admin': 'danger',
        'query_admin_logs': 'info',
        'add_admin': 'success',
        'register_admin': 'success',
        'update_admin': 'warning',
        'update_status': 'warning',
        'export_data': 'info',
        'upload_file': 'success',
        'download_file': 'info',
        'change_permission': 'warning',
        'view_feedback': 'info',
        'reply_feedback': 'success',
        'list_feedback': 'info',
        'query_user_detail': 'info',
        'query_self_logs': 'info',
        'get_announcements': 'info',
        'get_announcement_detail': 'info',
        'update_announcement': 'warning',
        'create_announcement': 'success',
        'delete_announcement': 'danger',
        'query_admin_list': 'info',
        'query_music_overview': 'info',
        'query_device_activity': 'info',
        'query_listening_distribution': 'info',
        'query_user_activity': 'info',
        'delete_device': 'danger',
        'get_feedback_replies': 'success',
        'change_authority': 'warning',
        'get_device_status_stats': 'info',
        'ban_admin': 'danger',
        'unban_admin': 'success',
        'account_banned': 'danger',
        'update_feedback_status': 'warning',
        'toggle_admin_active': 'danger',
      }
      
      return typeMap[operation] || 'info'
    },
    
    // 格式化失败原因
    formatReason(reason) {
      const reasonMap = {
        'password_incorrect': '密码错误',
        'account_not_found': '账户不存在',
        'account_disabled': '账户已禁用',
        'account_banned': '账号被禁用'
      }
      
      return reasonMap[reason] || reason
    },
    
    // 获取操作摘要
    getOperationSummary(log) {
      // 如果有reason，表示是失败操作，优先处理
      if (log.reason) {
        return `登录失败：${this.formatReason(log.reason)}`;
      }
      
      // 处理详情信息，优先展示详细操作信息
      if (log.details) {
        // 处理删除管理员操作
        if (log.operation === 'delete_admin') {
          // 从不同格式的details中提取被删除管理员信息
          if (log.details.target_admin_name) {
            return `删除了管理员账户：${log.details.target_admin_name}`;
          } else if (log.details.deleted_admin && log.details.deleted_admin.admin_name) {
            return `删除了管理员账户：${log.details.deleted_admin.admin_name}`;
          }
        }
        
        // 处理添加管理员操作
        if ((log.operation === 'add_admin' || log.operation === 'register_admin') && log.details && log.details.new_admin_name) {
          return `创建了新管理员：${log.details.new_admin_name}`;
        }
        
        // 处理更新管理员操作
        if (log.operation === 'update_admin' && log.details.updated_admin_name) {
          return `更新了管理员：${log.details.updated_admin_name}的信息`;
        }
        
        // 处理修改权限操作
        if (log.operation === 'change_authority') {
          if (log.details.target_admin_name) {
            return `修改了管理员：${log.details.target_admin_name}的权限`;
          }
        }
        
        // 处理禁用管理员操作
        if (log.operation === 'ban_admin' && log.details.target_admin_name) {
          return `禁用了管理员：${log.details.target_admin_name}`;
        }
        
        // 处理解禁管理员操作
        if (log.operation === 'unban_admin' && log.details.target_admin_name) {
          return `解禁了管理员：${log.details.target_admin_name}`;
        }
        
        // 处理管理员状态修改失败操作
        if (log.operation === 'toggle_admin_active' && log.details.target_admin_name) {
          return `修改管理员账户状态失败：${log.details.target_admin_name}`;
        }
        
        // 处理修改用户名操作
        if (log.operation === 'change_name' && log.details.new_admin_name) {
          return `修改了用户名为：${log.details.new_admin_name}`;
        }
        
        // 处理修改管理员名称操作
        if (log.operation === 'change_admin_name' && log.details.new_admin_name) {
          return `修改了用户名为：${log.details.new_admin_name}`;
        }
        
        // 处理删除设备操作
        if (log.operation === 'delete_device' && log.details.device_id) {
          return `删除了设备ID：${log.details.device_id}`;
        }
        
        // 处理更新反馈状态操作
        if (log.operation === 'update_feedback_status' && log.details.status) {
          return `更新了反馈状态为：${log.details.status}`;
        }
        
        // 处理查看用户详情操作
        if (log.operation === 'query_user_detail' && log.details.user_id) {
          return `查看了用户ID：${log.details.user_id}的详情`;
        }
      }
      
      // 如果没有匹配的details处理，使用默认描述
      switch(log.operation) {
        case 'query':
          return '查看了用户列表'
        case 'update':
          return '更新了系统信息'
        case 'delete':
          return '删除了系统数据'
        case 'create':
          return '创建了新记录'
        case 'delete_admin':
          return '删除了管理员账户'
        case 'query_admin_logs':
          return '查看了管理日志'
        case 'add_admin':
        case 'register_admin':
          return '创建了新管理员'
        case 'update_admin':
          return '更新了管理员信息'
        case 'update_status':
          return '更新了状态信息'
        case 'export_data':
          return '导出了系统数据'
        case 'upload_file':
          return '上传了文件'
        case 'download_file':
          return '下载了文件'
        case 'change_permission':
          return '修改了权限设置'
        case 'view_feedback':
          return '查看了用户反馈'
        case 'reply_feedback':
          return '回复了用户反馈'
        case 'list_feedback':
          return '查看了反馈中心'
        case 'query_user_detail':
          return '查看了用户详情'
        case 'query_self_logs':
          return '查看了个人操作日志'
        case 'get_announcements':
          return '查看了系统公告'
        case 'get_announcement_detail':
          return '查看了公告详情'
        case 'update_announcement':
          return '更新了系统公告'
        case 'create_announcement':
          return '发布了新公告'
        case 'delete_announcement':
          return '删除了系统公告'
        case 'query_admin_list':
          return '查看了管理员列表'
        case 'query_music_overview':
          return '查看了音乐数据概览'
        case 'query_device_activity':
          return '查看了设备活跃曲线'
        case 'query_listening_distribution':
          return '查看了听歌分布统计'
        case 'query_user_activity':
          return '查看了用户活跃数据'
        case 'delete_device':
          return '删除了用户设备'
        case 'password_change':
          return '修改了账户密码'
        case 'change_password':
          return '修改了账户密码'
        case 'change_name':
          return '修改了个人信息'
        case 'change_admin_name':
          return '修改了个人信息'
        case 'login':
          return '登录成功'
        case 'get_feedback_replies':
          return '回复了用户反馈'
        case 'change_authority':
          return '修改了管理员权限'
        case 'get_device_status_stats':
          return '查看了设备状态分布'
        case 'ban_admin':
          return '禁用了管理员'
        case 'unban_admin':
          return '解禁了管理员'
        case 'account_banned':
          return '账号被禁用'
        case 'update_feedback_status':
          return '更新了反馈状态'
        case 'delete_user':
          return '删除了用户'
        case 'add_device':
          return '添加了设备'
        case 'toggle_admin_active':
          return '修改管理员账户状态失败'
        default:
          return `执行了 ${log.operation} 操作`
      }
    },
    
    // 表格行类名
    tableRowClassName({ row }) {
      if (row.operation === 'login_failed') {
        return 'failed-row'
      }
      return ''
    },
    
    // 分页大小变化
    handleSizeChange(size) {
      this.pageSize = size
      // 重置当前页码，避免页码超出范围
      this.currentPage = 1
      // 重新加载数据
      this.fetchPageData()
    },
    
    // 分页页码变化
    handleCurrentChange(page) {
      this.currentPage = page
      // 加载当前页的数据
      this.fetchPageData()
    },
    
    handleOperationFilter() {
      // 切换筛选时，重置到第一页并重新请求数据
      this.currentPage = 1;
      // 选择筛选时，使用客户端筛选而不是发送请求
      if (!this.selectedOperation) {
        // 如果清除了筛选，重新获取所有数据
        this.fetchAdminLogs();
      }
    },
    
    loadMoreLogs() {
      if (this.loading) return;
      this.loading = true;
      const nextPage = this.currentPage + 1;
      const params = {
        page: nextPage,
        page_size: this.pageSize
      };
      if (this.selectedOperation) {
        params.operation = this.selectedOperation;
      }
      const requestConfig = {
        headers: {
          'adminID': this.adminInfo.admin_id
        },
        params: params
      };
      if (axios.defaults.headers.common['adminID']) {
        requestConfig.headers['adminID'] = axios.defaults.headers.common['adminID'];
      }
      const apiUrl = 'https://smartsound.top/api/v1/admin/log_activity';
      axios.get(apiUrl, requestConfig)
        .then(response => {
          if (response.data && response.data.code === 0) {
            const data = response.data.data;
            let newLogs = [];
            if (Array.isArray(data)) {
              newLogs = data;
            } else if (data.logs) {
              newLogs = data.logs || [];
            }
            // 过滤掉operation为'register'的日志
            newLogs = newLogs.filter(log => log.operation !== 'register');
            // 追加去重
            const dedupMap = new Map();
            [...this.logs, ...newLogs].forEach(log => {
              let normalizedOperation = log.operation;
              if (log.operation === 'register_admin') normalizedOperation = 'add_admin';
              const key = `${log.timestamp.substr(0, 16)}_${log.admin_name}_${normalizedOperation}_${log.ip}`;
              if (!dedupMap.has(key)) {
                dedupMap.set(key, log);
              } else {
                const exist = dedupMap.get(key);
                const hasDetails = log.details && (
                  (normalizedOperation === 'add_admin' && log.details.new_admin_name) ||
                  (normalizedOperation === 'delete_admin' && (log.details.target_admin_name ||
                    (log.details.deleted_admin && log.details.deleted_admin.admin_name)))
                );
                const existHasDetails = exist.details && (
                  (normalizedOperation === 'add_admin' && exist.details.new_admin_name) ||
                  (normalizedOperation === 'delete_admin' && (exist.details.target_admin_name ||
                    (exist.details.deleted_admin && exist.details.deleted_admin.admin_name)))
                );
                if (hasDetails && !existHasDetails) {
                  dedupMap.set(key, log);
                }
              }
            });
            this.logs = Array.from(dedupMap.values());
            this.currentPage = nextPage;
            this.serverTotalLogs = data.pagination ? data.pagination.total_logs : this.logs.length;
          } else {
            const errorMsg = response.data.message || response.data.msg || '未知错误';
            ElMessage.error('加载更多失败: ' + errorMsg);
          }
        })
        .catch(() => {
          ElMessage.error('加载更多失败，请稍后重试');
        })
        .finally(() => {
          this.loading = false;
        });
    }
  }
}
</script>

<style scoped>
.admin-container {
  padding: 16px 5px;
  position: relative;
  margin-bottom: 80px;
  background-color: #f5f7fa;
}

/* 页面标题区域 */
.page-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  background: linear-gradient(135deg, #1890ff, #722ed1);
  color: white;
  border-radius: 12px;
  padding: 32px 40px;
  margin-bottom: 35px;
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.15);
  overflow: hidden;
  position: relative;
}

.page-header::after {
  content: '';
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 50%;
  background: rgba(255, 255, 255, 0.1);
  transform: skewX(-20deg);
}

.header-content {
  z-index: 1;
}

.page-title {
  font-size: 28px;
  margin: 0 0 12px 0;
  font-weight: 600;
  text-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.page-description {
  font-size: 16px;
  margin: 0;
  opacity: 0.9;
  line-height: 1.6;
}

.page-actions {
  z-index: 1;
  display: flex;
  gap: 10px;
}

/* 行容器样式 */
.row-container {
  margin-bottom: 30px;
  position: relative;
  z-index: 0;
}

/* 卡片基本样式 */
.el-card {
  border-radius: 12px;
  box-shadow: 0 5px 15px rgba(0, 0, 0, 0.08);
  border: none;
  transform: translate3d(0, 0, 0);
  will-change: transform;
  transition: all 0.3s;
}

.el-card:hover {
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.12);
  transform: translateY(-2px);
  z-index: 1;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px 20px;
  border-bottom: 1px solid #ebeef5;
  background: linear-gradient(to right, #f0f5ff, #fafbff);
}

.card-title {
  font-size: 18px;
  font-weight: 600;
  margin-right: 12px;
  color: #1e3799;
  display: flex;
  align-items: center;
  gap: 8px;
}

.card-title i {
  font-size: 22px;
  color: #4481eb;
}

/* 表格卡片样式 */
.table-card {
  background: linear-gradient(to bottom, #ffffff, #fafbff);
  overflow: hidden;
}

/* 表格样式 */
.el-table {
  margin: 10px 0;
  border-radius: 12px;
  overflow: hidden;
  --el-table-border-color: #e8edf3;
  --el-table-header-bg-color: #f0f5ff;
  table-layout: fixed;
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.08);
}

/* 管理日志表格的特殊样式 */
.admin-log-table {
  --el-table-border: 1px solid #e8edf3;
  --el-table-text-color: #303133;
  --el-table-header-text-color: #1e3799;
  font-size: 14px;
  animation: fadeIn 0.6s ease-in-out;
}

@keyframes fadeIn {
  from { opacity: 0; transform: translateY(10px); }
  to { opacity: 1; transform: translateY(0); }
}

.admin-log-table th.el-table__cell {
  background-color: #f0f5ff;
  font-weight: 600;
  letter-spacing: 0.5px;
  position: relative;
}

.admin-log-table th.el-table__cell::after {
  content: '';
  position: absolute;
  bottom: 0;
  left: 50%;
  transform: translateX(-50%);
  width: 40px;
  height: 3px;
  background: linear-gradient(90deg, #1e3799, #4481eb);
  border-radius: 3px;
}

.admin-log-table .el-table__header-wrapper {
  border-bottom: 2px solid #dcdfe6;
}

/* 表格行样式 */
.admin-log-table .el-table__row {
  transition: all 0.3s;
}

.admin-log-table .el-table__row:hover {
  background-color: #f5f9ff !important;
  transform: translateY(-1px);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}

.admin-log-table .failed-row {
  background-color: rgba(245, 108, 108, 0.05);
}

.admin-log-table .failed-row td {
  transition: all 0.3s;
}

.admin-log-table .failed-row:hover td {
  background-color: rgba(245, 108, 108, 0.1) !important;
}

.el-table .el-table__header th {
  padding: 16px 10px;
}

.el-table .el-table__row td {
  padding: 14px 10px;
  vertical-align: middle;
  border-bottom: 1px solid #ebeef5;
}

.el-table .cell {
  padding: 0 18px;
  line-height: 1.6;
  word-break: break-word;
}

.el-table--border .el-table__cell {
  border-right: 1px solid var(--el-table-border-color);
}

.time-column {
  font-family: 'Roboto Mono', monospace;
  white-space: nowrap;
  font-size: 14px;
  letter-spacing: 0.5px;
  width: 95%;
  margin: 0 auto;
  color: #333;
  background: linear-gradient(120deg, #f8f9fa 0%, #f0f5ff 100%);
  padding: 6px 10px;
  border-radius: 8px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.06);
  transition: all 0.3s ease;
}

.time-column:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
  background: linear-gradient(120deg, #f0f5ff 0%, #e6f0ff 100%);
}

.time-display {
  display: flex;
  align-items: center;
  justify-content: center;
}

.time-display span {
  font-weight: 500;
  color: #1e3799;
  background-color: rgba(64, 158, 255, 0.1);
  padding: 4px 10px;
  border-radius: 4px;
  display: block;
  width: 100%;
  text-align: center;
}

.ip-address {
  font-family: 'Roboto Mono', monospace;
  cursor: pointer;
  color: #4481eb;
  transition: all 0.3s;
  display: block;
  text-align: center;
  font-size: 14px;
  letter-spacing: 0.5px;
  width: 95%;
  margin: 0 auto;
  padding: 6px 10px;
  background-color: #f9fafc;
  border-radius: 4px;
  border: 1px solid #ebeef5;
}

.ip-address:hover {
  color: #1e3799;
  text-decoration: underline;
  background-color: #f0f5ff;
  border-color: #4481eb;
  box-shadow: 0 2px 6px rgba(68, 129, 235, 0.1);
}

/* 展开行样式 */
.expanded-log {
  background-color: #f9fafc;
  padding: 16px 24px;
  border-radius: 8px;
  margin: 0 24px 16px;
  box-shadow: inset 0 0 10px rgba(0, 0, 0, 0.05);
}

.log-details {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.detail-item {
  display: flex;
  align-items: flex-start;
  line-height: 1.5;
}

.detail-label {
  min-width: 120px;
  font-weight: 600;
  color: #606266;
  margin-right: 12px;
}

.detail-value {
  color: #303133;
  word-break: break-word;
}

.detail-section {
  margin-top: 12px;
  border-top: 1px dashed #dcdfe6;
  padding-top: 12px;
}

.indent {
  margin-left: 20px;
}

.detail-json {
  background-color: #f0f2f5;
  padding: 12px;
  border-radius: 4px;
  color: #303133;
  font-family: monospace;
  font-size: 13px;
  max-width: 100%;
  overflow-x: auto;
  white-space: pre-wrap;
  word-break: break-word;
}

.log-summary {
  display: flex;
  align-items: center;
  justify-content: flex-start;
  padding: 2px 0;
  border-radius: 4px;
  transition: all 0.2s;
}

.log-summary:hover {
  background-color: #f5f7fa;
}

.operation-summary {
  color: #303133;
  font-size: 14px;
  text-align: left;
  display: block;
  width: 100%;
  padding: 0 5px;
  line-height: 1.5;
  font-weight: 500;
}

/* 表格内标签样式 */
.el-table .el-tag {
  display: inline-block;
  text-align: center;
  min-width: 110px;
  margin: 0 auto;
  padding: 0 16px;
  transition: all 0.3s;
}

.admin-log-table .el-tag--small {
  height: 28px;
  line-height: 28px;
  font-size: 13px;
}

.admin-log-table .admin_name-column .el-tag {
  width: 90%;
  max-width: 150px;
  background-color: #ecf5ff;
  color: #409EFF;
  border-color: #d9ecff;
  padding: 6px 12px;
  height: 32px;
  line-height: 20px;
  font-size: 14px;
  font-weight: 500;
  box-shadow: 0 2px 6px rgba(64, 158, 255, 0.1);
}

.admin-log-table .admin_name-column .el-tag:hover {
  transform: translateY(-1px);
  box-shadow: 0 3px 8px rgba(64, 158, 255, 0.2);
  background-color: #e0f0ff;
}

.admin-log-table .operation-column .el-tag {
  width: 95%;
  max-width: 260px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  font-size: 13px;
  font-weight: 500;
  padding: 6px 12px;
  height: 32px;
  line-height: 20px;
  border: none;
  white-space: nowrap;
  overflow: visible;
  text-overflow: unset;
}

.admin-log-table .operation-tag.el-tag--success {
  background: linear-gradient(135deg, #52c41a, #73d13d);
}

.admin-log-table .operation-tag.el-tag--danger {
  background: linear-gradient(135deg, #f5222d, #ff4d4f);
}

.admin-log-table .operation-tag.el-tag--warning {
  background: linear-gradient(135deg, #fa8c16, #ffa940);
}

.admin-log-table .operation-tag.el-tag--info {
  background: linear-gradient(135deg, #1890ff, #40a9ff);
}

.admin-log-table .details-column .detail-tag {
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
  transition: all 0.3s;
}

.admin-log-table .details-column .detail-tag:hover {
  transform: translateY(-1px);
  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.15);
}

/* 详细信息列样式 */
.details-column .cell {
  padding-left: 18px;
  text-align: left;
}

/* 分页控件 */
.pagination {
  margin-top: 20px;
  display: flex;
  justify-content: flex-end;
}

/* 浮动操作区 */
.floating-actions {
  position: fixed !important;
  right: 24px !important;
  bottom: 24px !important;
  display: flex !important;
  flex-direction: column !important;
  align-items: center !important;
  z-index: 100 !important;
}

.refresh-btn {
  margin: 0 !important;
  border-radius: 50% !important;
  width: 52px !important;
  height: 52px !important;
  padding: 0 !important;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  background: linear-gradient(135deg, #2196F3, #1E88E5) !important;
  border: none !important;
  box-shadow: 0 4px 12px rgba(33, 150, 243, 0.4) !important;
  transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1) !important;
  overflow: hidden !important;
}

.refresh-btn:hover {
  transform: translateY(-3px) !important;
  box-shadow: 0 6px 16px rgba(33, 150, 243, 0.5) !important;
  background: linear-gradient(135deg, #1E88E5, #1976D2) !important;
}

.refresh-btn:active {
  transform: translateY(0) !important;
  box-shadow: 0 2px 8px rgba(33, 150, 243, 0.4) !important;
}

.refresh-btn::after {
  content: '' !important;
  position: absolute !important;
  top: 0 !important;
  left: 0 !important;
  width: 100% !important;
  height: 100% !important;
  background: radial-gradient(circle, rgba(255,255,255,0.3) 0%, rgba(255,255,255,0) 70%) !important;
  opacity: 0 !important;
  transition: opacity 0.3s ease !important;
  pointer-events: none !important;
}

.refresh-btn:hover::after {
  opacity: 1 !important;
}

.refresh-btn .el-icon {
  font-size: 24px !important;
  color: white !important;
  animation: fadeIn 0.3s ease-out !important;
}

/* 底部安全区域 */
.bottom-safe-area {
  height: 60px;
  width: 100%;
  margin-top: 20px;
}

/* 响应式调整 */
@media (max-width: 768px) {
  .page-header {
    flex-direction: column;
    align-items: flex-start;
    padding: 24px;
  }
  
  .page-actions {
    margin-top: 20px;
    flex-wrap: wrap;
  }
  
  .page-title {
    font-size: 24px;
  }
  
  .floating-actions {
    right: 16px;
    bottom: 16px;
  }
}

.operation-type-container {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  padding: 0 5px;
}

.operation-tag {
  font-weight: 500;
  letter-spacing: 0.5px;
  border-radius: 4px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  min-width: 160px;
  transition: all 0.3s;
  width: auto;
}

.operation-tag:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

/* 分页信息提示 */
.pagination-info {
  margin-top: 10px;
  text-align: center;
}

.divider-content {
  font-weight: 500;
  color: #606266;
  font-size: 14px;
  padding: 0 10px;
}

/* 无数据提示 */
.no-data-tip {
  padding: 40px 0;
  text-align: center;
}

/* 空状态优化 */
.no-data-tip {
  padding: 60px 0;
  text-align: center;
  background: linear-gradient(135deg, #f5f7fa 0%, #f0f5ff 100%);
  border-radius: 8px;
  margin: 20px;
}

.no-data-tip .el-empty__description {
  font-size: 16px;
  color: #606266;
  margin-bottom: 20px;
}

/* 禁用状态的视觉反馈 */
.el-button:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.el-input.is-disabled {
  opacity: 0.6;
}

/* 加载状态的表格遮罩优化 */
.el-table.el-table--enable-row-hover .el-table__body tr:hover > td {
  background-color: #f5f7fa !important;
}

.el-loading-mask {
  background-color: rgba(255, 255, 255, 0.95);
}
</style> 